package com.example.demo;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;

import java.net.InetSocketAddress;

/**
 * @author fanhang
 */
public class NettyServer {
    private final int port;
    private final ServerBootstrap bootstrap;

    public NettyServer(ChannelHandler httpHandler, int port) {
        this.port = port;
        this.bootstrap = new ServerBootstrap();
        EventLoopGroup boss = new NioEventLoopGroup();
        EventLoopGroup work = new NioEventLoopGroup();
        bootstrap.group(boss, work)
            .handler(new LoggingHandler(LogLevel.DEBUG))
            .channel(NioServerSocketChannel.class)
            .childHandler(new HttpChannelInitializer(httpHandler));
    }

    public void start() throws InterruptedException {
        ChannelFuture f = bootstrap.bind(new InetSocketAddress(port)).sync();
        System.out.println("server start up on port : " + port);
        f.channel().closeFuture().sync();
    }


    private static class HttpChannelInitializer extends ChannelInitializer<NioSocketChannel> {
        private final ChannelHandler httpHandler;

        public HttpChannelInitializer(ChannelHandler httpHandler) {
            this.httpHandler = httpHandler;
        }

        @Override
        protected void initChannel(NioSocketChannel channel) throws Exception {
            ChannelPipeline pipeline = channel.pipeline();
            pipeline.addLast(new HttpServerCodec());// http 编解码
            pipeline.addLast("httpAggregator", new HttpObjectAggregator(512 * 1024)); // http 消息聚合器                                                                     512*1024为接收的最大contentlength
            pipeline.addLast(httpHandler);
        }
    }
}
